/*
 * TabuSearch.h
 *
 *  Created on: Jun 2, 2009
 *      Author: ruslan
 */

#ifndef TABUSEARCH_H_
#define TABUSEARCH_H_

#include <list>

#include "Search.h"

using namespace std;

class TabuSearch: public Search {
public:
	TabuSearch(int weeks, int groupsInWeek, int playersInGroup, long maxIteration);
	virtual ~TabuSearch();

	virtual void init();
	virtual int ScheduleIt();
	void setAdditionalParams(int _START_INIT_ALG
			,long _FAST_SOLUTION_MAX_ITERATION
			, int _MIN_PLAYER_PENALTY
			, int _MAX_PLYAER_PENALTY
			, int _MAX_NEIGHBOURS
			, int _TABLE_CHANGE_REGIME
			, int _MAX_WAITING_OF_PROGRESS
			, int _MAX_SOFT_PERTURBATIONS
			, int _FREQUENCY_FOR_LAST_ITERATIONS
			, int _CHOOSE_OFTEN_PLYAER_SWAPS);
	virtual string getParametersAsString();

private:
	void preInit();
	void getFastSolution();
	void applyFastSolution();
	void GenerateNeighbor(list<int*>&);
	void GenerateNeighbor2(list<int*>& neighborhoodList, list<int*>& bestNeighborhoodList/*don't delete pointrs!*/, list<int*>& worstNeighborhoodList/*don't delete pointrs!*/);
	int* ChooseBestVariant(list<int*>&);
	int* ChooseBestVariant2(list<int*>& bestNonTabuNeighborhoodList, list<int*>& bestTabuNeighborhoodList, int often);
	void snapshot();
	void applyChanges(int*);
	void updateConflictStatus(int player1, int player2, bool addConflict, int exceptWeek);
	void hardPerturbation();
	void softPerturbation();
	void softPerturbations();
	void rndPlayersChangeForHardPerturbation();

	int START_INIT_ALG;
	long FAST_SOLUTION_IN_MkSec;
	long FAST_SOLUTION_MAX_ITERATION;
	int MIN_PLAYER_PENALTY;
	int MAX_PLYAER_PENALTY;
	int MAX_NEIGHBOURS;
	int TABLE_CHANGE_REGIME; //0 - there is not changing, 1 - change every iteration, 2 - change till delata=0
	list<int> tablesIndecesForNeighboursGeneration;
	int MAX_WAITING_OF_PROGRESS;
	int MAX_SOFT_PERTURBATIONS;

	int FREQUENCY_FOR_LAST_ITERATIONS;
	int lowFrequencyThreshould;
	int CHOOSE_OFTEN_PLYAER_SWAPS;

	bool additionalParamsWasSet;

	int** mtrxGames; // count of games for every pair (Conflicts)
	int**** mtrx4Tabu; // tabu list for every weeks
	list<int>** mtrxConflictIndecesLists; // conflict indeces for every week
	int*** mtrx3ConflictIndeces; // for conflict position [i,j,k] >0 and is equal to quantity of elements in group with whom player has more than 1 game
	int minConflicts;
	int currConflicts;
};

#endif /* TABUSEARCH_H_ */
